package com.zhyl.detectibrary.util;

import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
import org.bouncycastle.openssl.PEMParser;
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.KeyStore;
import java.security.PublicKey;
import java.security.Signature;
import java.security.cert.Certificate;

import cn.hutool.core.codec.Base64;

public class SignatureVerifier {

    public static boolean verifySignatureByPubkey(byte[] data, byte[] signatureBytes, PublicKey publicKey) throws Exception {
        // 使用相同的算法进行签名验证
        Signature signature = Signature.getInstance("SHA256withRSA");
        signature.initVerify(publicKey);
        signature.update(data);

        // 验证签名
        return signature.verify(signatureBytes);
    }

    public static boolean verifySignatureWithBase64ByPubkey(String dataString, String base64Signature, String keyStorePath) {
        try {
            // 将Base64字符串解码为签名的二进制数据
            byte[] dataBytes = dataString.getBytes("UTF-8");
            byte[] signatureBytes = Base64.decode(base64Signature);
            // 加载KeyStore
            PublicKey publicKey = loadPublicKeyFromPEM(keyStorePath);
            // 验证签名
            return verifySignatureByPubkey(dataBytes, signatureBytes, publicKey);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e.getMessage());
        }
    }

    public static boolean verifySignatureWithBase64ByPubkey(String dataString, String base64Signature, InputStream keyInputStream) {
        try {
            // 将Base64字符串解码为签名的二进制数据
            byte[] dataBytes = dataString.getBytes("UTF-8");
            byte[] signatureBytes = Base64.decode(base64Signature);
            // 加载KeyStore
            PublicKey publicKey = loadPublicKeyFromPEM(keyInputStream);
            // 验证签名
            return verifySignatureByPubkey(dataBytes, signatureBytes, publicKey);
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException(e.getMessage());
        }
    }

    public static PublicKey loadPublicKeyFromPEM(String publicKeyPath) throws Exception {
        BufferedReader reader = new BufferedReader(new FileReader(publicKeyPath));
        PEMParser pemParser = new PEMParser(reader);

        JcaPEMKeyConverter converter = new JcaPEMKeyConverter();
        Object object = pemParser.readObject();
        PublicKey publicKey = converter.getPublicKey((SubjectPublicKeyInfo) object);

        pemParser.close();
        reader.close();

        return publicKey;
    }

    public static PublicKey loadPublicKeyFromPEM(InputStream inputStream) throws Exception {
        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
        PEMParser pemParser = new PEMParser(reader);

        JcaPEMKeyConverter converter = new JcaPEMKeyConverter();
        Object object = pemParser.readObject();
        PublicKey publicKey = converter.getPublicKey((SubjectPublicKeyInfo) object);

        pemParser.close();
        reader.close();

        return publicKey;
    }


}

